<body>
<div id='game'>
	<div class='heading'><h1 id='title'></h1><span id='by'></span></div>
	<div id='play'><canvas id='target' width=512 height=256></canvas></div>
	<div id='meta'>
		<div>Released: <span id='release'></span></div>
		<div>Platform: <span id='platform'></span></div>
		<div><a id='download' href='#'>Download Rom</a></div>
		<div><a id='source' href='#'>Source and Details</a></div>
	</div>
</div>
</body>

<style>
body{font-family:Helvetica;margin-left:10%;margin-right:10%;margin-top:5%;}
h1,#meta>div{font-family:Futura;display:inline-block;margin:20px;}
.heading,#meta{background:gray;}
canvas{border:1px solid black;}
#game{background:gray;border-radius:14px;background:lightgray;overflow:hidden;}
#play{display:flex;justify-content:center;padding:20px;}
#meta{display:flex;justify-content:space-between;}
</style>

<script src='https://johnearnest.github.io/Octo/js/emulator.js'></script>
<script src='https://johnearnest.github.io/Octo/js/shared.js'></script>
<script src='https://johnearnest.github.io/Octo/js/input.js'></script>
<script>
id=x=>document.querySelector('#'+x)
send=(u,t)=>{let r=new XMLHttpRequest();return r.open('GET',u),r.responseType=t,r.send(),r}
ajax=(u,t,f)=>{let r=send(u,t);r.onreadystatechange=_=>r.readyState==4&&f(r.response)}

const emulator = new Emulator()

function run(options,rom) {
	unpackOptions(emulator, options)
	setRenderTarget(4, 'target')
	emulator.init(rom)
	emulator.importFlags = _=> JSON.parse(localStorage.getItem('octoFlagRegisters'))
	emulator.exportFlags = x=> localStorage.setItem('octoFlagRegisters', JSON.stringify(x))
	try { localStorage.getItem('octoFlagRegisters') }
	catch(e) {
		console.warn("Persistent flag register storage is unavailable! Flag registers will not be saved across sessions.")
		emulator.importFlags = _ => emulator.flags
		emulator.exportFlags = x => emulator.flags = x
	}
	emulator.buzzTrigger = (ticks,rest)=> playPattern(ticks, emulator.pattern, rest)

	const kd = e=>{
		if (!audio) audioSetup(emulator)
		if (!(e.key in emulator.keys)) emulator.keys[e.key]=true
		e.preventDefault()
	}
	const ku = e=>{
		if (e.key in emulator.keys) delete emulator.keys[e.key]
		if (!emulator.waiting) return
		const kindex = keymapInverse[e.key]
		if (kindex != undefined) {
			emulator.waiting = false
			emulator.v[emulator.waitReg] = kindex
		}
		e.preventDefault()
	}
	window.addEventListener('keydown',kd,false)
	window.addEventListener('keyup',ku,false)
	const frameTime=1000/60
	let last=Date.now(), origin=last+frameTime/2
	intervalHandle=setInterval(_=>{
		last+=(Date.now()-last)
		if (emulator.halted) return
		for(var k=0; origin<last-frameTime&&k<2; origin+=frameTime,k++){
			for(var z=0;(z<emulator.tickrate) && (!emulator.waiting); z++){
				if (emulator.vBlankQuirks &&((emulator.m[emulator.pc] & 0xF0)==0xD0)) z=emulator.tickrate
				emulator.tick()
			}
			if (emulator.dt > 0) emulator.dt--
			if (emulator.st > 0) emulator.st--
			XOAudio && XOAudio.refresh(frameTime/1000)
		}
		renderDisplay(emulator)
		id('game').style.backgroundColor = emulator.st?emulator.buzzColor:emulator.quietColor
	}, frameTime)
	injectAdaptiveControls(emulator.touchInputMode,document.getElementById('target'),ku,kd)
}

ajax('programs.json','',x=>{
	const slug=new URLSearchParams(document.location.search).get('p')
	const g=JSON.parse(x)[slug]
	id('title').innerHTML=g.title
	id('release').innerHTML=g.release||'Unknown'
	id('platform').innerHTML=g.platform||'Unknown'
	id('download').href='roms/'+slug+'.ch8'
	id('source').href='https://github.com/JohnEarnest/chip8Archive/tree/master/src/'+slug
	ajax('authors.json','',x=>{
		const a=JSON.parse(x)
		id('by').innerHTML='by '+g.authors.map(
			x=>a[x].url?`<a href='${a[x].url}'>${x}</a>`:x
		).join(', ')
	})
	ajax('roms/'+slug+'.ch8','arraybuffer',x=>{
		run(g.options||{},{rom:new Uint8Array(x)})
	})
})
</script>
